package com.cskaoyan.javase.object._2tostring;

/**
 * toString方法：
 * 1.方法的声明：public String toString()
 *      没有什么需要注意的地方，访问权限不用管
 *      方法不需要参数，但是方法有String类型的返回值
 *
 * 2.方法的作用：
 *      1.返回该对象的字符串表示。
 *      2.通常，toString方法会返回一个“以文本方式表示”此对象的字符串。
 *      3.结果应是一个简明但易于读懂的信息表达式。
 *      4.建议所有子类都重写此方法。
 * 3.Object类当中默认的实现方法体:
 *      return getClass().getName() + "@" + Integer.toHexString(hashCode());
 *      hashCode方法是获取对象的哈希值,默认实现是通过计算对象的地址得出一个十进制的整数
 *          这个整数可以看成这个对象的地址值
 *      这个方法的实现是:
 *          全限定类名 + "@" + 十六进制的地址值
 *      以往,我们直接输出一个对象的对象名时,就会打印以上方法实现
 *
 *      实际上,在Java当中,只要对象参于"输出,或者字符串拼接"运算,都会隐式调用
 *          该对象的toString方法
 *
 * 4.打印对象得到地址值,很多时候不是我们想要的,所以需要在类中重写toString方法
 *      一般情况下,我们都会选择打印对象的属性取值,来表示这个对象
 *      重写方法,如无特别需求,大多情况下快捷键alt+insert自动生成即可.
 *      注:
 *          实际开发中,建议用StringBuffer或者StringBuilder这两个类做字符串拼写
 *
 * 注意事项:
 *       1.toString方法就是为了将对象以字符串的形式输出,不要在toString方法中乱写代码,尤其是赋值等语句
 *          可以会导致错误.
 *          尤其是debug模式下,执行走过对象创建的语句
 *          会自动调用该类的toString方法
 *          从而导致debug模式下代码出错,run模式下代码正常.
 *
 *       2.如果对象的成员变量中,有引用数据类型
 *          如果是String,那直接拼接就可以了.
 *          如果是一个自定义的类,那么需要再重写它的toString方法,否者仍然打印地址值.
 *
 *       3.隐式调用toString方法有没有必须写出来?
 *          不要画蛇添足,写出来就有空指针异常的风险
 *          建议不要写出来
 *          即便有null元素,也会打印null,而不是异常
 *
 *
 * @since 10:10
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {

        Student s = new Student(18, 100);
        // System.out.println(s);
        System.out.println(s.age);


        System.out.println("--------------");
        Student s2 = new Student(18, 100, new Teacher(28));
        System.out.println(s2);
        System.out.println(s.toString());
        System.out.println(s2.toString());
    }
}

class Student {
    int age;
    double score;
    Teacher t;

    public Student(int age, double score) {
        this.age = age;
        this.score = score;
    }

    public Student() {
    }

    public Student(int age, double score, Teacher t) {
        this.age = age;
        this.score = score;
        this.t = t;
    }
    // 重写toString
    /*@Override
    public String toString() {
        return "Student{ age =" + age + ", score = " + score + "}";
    }*/

    /*@Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", score=" + score +
                '}';
    }*/

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", score=" + score +
                ", t=" + t +
                '}';
    }
}

class Teacher{
    int age;

    public Teacher() {
    }

    public Teacher(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "age=" + age +
                '}';
    }
}